#!/usr/bin/env python 3.2
#Authors: Russell P. Nowell, Brian Lynch, Angela Dixie Lynch
#Copyright 2012 All rights reserved.
#This is open source: You may use this program under the new BSD license.
#
## To do: 1. Set up file input of Replacements Dictionary
##      2. Set up query for setting forms directory in Defaults file.
##      3. Set up query for changing output path in defaults file.
##      4. Add ability to work in binary word processing files -- 
##          specifically zipped ODT, Word, and Worperfect.
##      5. Add error handling for forms directory not found, forms file not found
##          output directory not found, output file exists in new directory,
##          overwrite?
##      6. Check against Pep Style guide and docstrings guidelines.
##      7. Restrict imports to portions of packages used.
##      8. Bundle for Alpha distribution.
#
#
#Document Assembly - Up and Running Version Specific to Law Office
#  ** Working copy == Change forms path, change outpath to fresh directory
#     client or project, Edit forms files placing variable names at correct text.
#     Use save as Windows Generic Word Processor to avoid form text file having
#     spaces and tabs within paragraphs.
#     Edit replacements dictionary (I prefer to keep a separate
#     one for each project. My average project has over 20 form documents,
#     with one over 30 pages, to be produced for a closing, with 
#     hundreds of replacements. It runs in about 3 seconds.

#Inputs:
#   1) input directory and extension of form files
#   2) output directory of working files for text replacement
#   3) input replacements dictionary for 'search' : 'replace' iteration through
#       output files
#Returns: Files in specified output directory with replacements.

######## IMPORTS
import fileinput
import sys
import os
import shutil
import glob
import pprint
import getopt

######### Variables
# forward slash is usable by all operating systems in Python
path = 'C:/MimusDA/forms/'             ##Change forms path
outpath = 'C:/MimusDA/forms/output/'   ##Change output directory, create manually
filepattern = '*.txt'                  ##Change file pattern of form and output files.
# Multiple replacement dictionary definition ## Change replacement dictionary 
replacements = {'F1' : 'FOO',
                'F2' : 'BAR',
                'F3' : 'HOKUM',
                'FSettlor' : 'John Doe',
                'FTrustee' : 'Jane Roe'}

#Test Section: Display variables before operation
print('The following files will be selected: ', filepattern)
print('The form files will be selected from: ', path)
print('The form files will be copied to: ', outpath)
print('The search/replace values: ')
pprint.pprint(replacements)

def directory_existence(directory_path_name):
    '''
    Determine if a directory exists. If directory does not exist, create it. If directory does exist, do nothing.
    '''
    if not os.path.exists(directory_path_name):
      os.makedirs(directory_path_name)

def formscopy():
    '''Copy all files with filepattern from form files directory (path)
    to project or client file directory (outpath)

    '''
    #ensure directory existence
    directory_existence(path) 
    
    #Change to forms path
    os.chdir(path)                      
    checkcwd = os.getcwd()
    
    #Test that cwd = outpath
    print('Current working directory is now ', checkcwd)

    # Test to determine filenames in forms\output
    for filename in os.listdir(path):
        print(filename, ' copied from ', path, ' to ', outpath)
        #Terminate if no input files defined
        if filename == []:
            raise Exception('No input files defined with current path and extension')
        #Terminate if overwriting output files.
        if os.path.isfile(os.path.join(outpath,filename)) == True:
            raise Exception('Overwriting output files')


    # Copy all 'ext' files from forms to forms\output
    for filename in glob.glob(os.path.join(path, filepattern)):
        shutil.copy(filename, outpath)

def formsreplace():
    '''Replace text from dictionary replacements keys to values
    in all filepattern files in outpath

    '''
    #ensure directory exists
    directory_existence(outpath)

    # Change to working copy path so as to not destroy the form files
    os.chdir(outpath)
    checkcwd = os.getcwd()
    #Test that cwd = outpath
    print('Current working directory is ', checkcwd)

    # Populate the filenames variable from the output path for use
    # in the fileinput statement
    filename = glob.glob(os.path.join(outpath, filepattern))
    
    #Test filenames for replacement operation
    print('The following files will be searched and replaced: ')
    pprint.pprint(filename)
    
    #Terminate if search and replace file list is empty.
    if filename == []:
        raise Exception('No output files defined with current path and extension')

    # Use fileinput inline replacement to iterate each dictionary key value pair
    # through each line of each file
    for line in fileinput.input(filename, inplace = True):
        for k, v in replacements.items():
            line = line.replace(k, v)
        sys.stdout.write(line)

class Usage(Exception):
    def __init__(self, msg):
        self.msg = msg

def main(argv=None):
    if argv is None:
        argv = sys.argv
    try:
        try:
            opts, args = getopt.getopt(argv[1:], 'h', ['help'])
        except getopt.GetoptError as msg:
             raise Usage(msg)
        #call functions
        formscopy()
        formsreplace()
        return 0
    except Usage as err:
        print(err.msg, file='sys.stderr')
        print("for help use --help", file='sys.stderr')
        return 2

if __name__ == '__main__':
    try:
        sys.exit(main())
    except SystemExit:
        print('MimusDA has completed your multi-file search and replace.')
